package com.example.security.service;

import com.example.security.exception.BusinessException;
import com.example.security.sso.SsoClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * SSO客户端服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SsoClientService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    
    /**
     * 注册客户端
     */
    public void registerClient(String clientId, String clientUrl) {
        if (!StringUtils.hasText(clientId) || !StringUtils.hasText(clientUrl)) {
            throw new IllegalArgumentException("客户端ID和URL不能为空");
        }
        
        try {
            SsoClient client = new SsoClient(clientId, clientUrl);
            redisTemplate.opsForHash().put(getClientsKey(), clientId, client);
            log.info("注册客户端成功: clientId={}, url={}", clientId, clientUrl);
        } catch (Exception e) {
            log.error("注册客户端失败: clientId=" + clientId, e);
            throw new RuntimeException("注册客户端失败", e);
        }
    }
    
    /**
     * 验证客户端
     */
    public void validateClient(String clientId, String clientSecret) {
        if (!StringUtils.hasText(clientId) || !StringUtils.hasText(clientSecret)) {
            throw new IllegalArgumentException("客户端ID和密钥不能为空");
        }
        
        try {
            SsoClient client = getClient(clientId);
            if (client == null) {
                throw new BusinessException("客户端不存在");
            }
            
            if (client.getStatus() != 1) {
                throw new BusinessException("客户端已禁用");
            }
            
            if (!clientSecret.equals(client.getClientSecret())) {
                throw new BusinessException("客户端密钥错误");
            }
            
            log.debug("验证客户端成功: clientId={}", clientId);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("验证客户端失败: clientId=" + clientId, e);
            throw new RuntimeException("验证客户端失败", e);
        }
    }
    
    /**
     * 获取客户端信息
     */
    public SsoClient getClient(String clientId) {
        if (!StringUtils.hasText(clientId)) {
            return null;
        }
        return (SsoClient) redisTemplate.opsForHash().get(getClientsKey(), clientId);
    }
    
    /**
     * 更新客户端状态
     */
    public void updateClientStatus(String clientId, Integer status) {
        try {
            SsoClient client = getClient(clientId);
            if (client != null) {
                client.setStatus(status);
                redisTemplate.opsForHash().put(getClientsKey(), clientId, client);
                log.info("更新客户端状态成功: clientId={}, status={}", clientId, status);
            }
        } catch (Exception e) {
            log.error("更新客户端状态失败: clientId=" + clientId, e);
            throw new RuntimeException("更新客户端状态失败", e);
        }
    }
    
    /**
     * 删除客户端
     */
    public void removeClient(String clientId) {
        try {
            redisTemplate.opsForHash().delete(getClientsKey(), clientId);
            log.info("删除客户端成功: clientId={}", clientId);
        } catch (Exception e) {
            log.error("删除客户端失败: clientId=" + clientId, e);
            throw new RuntimeException("删除客户端失败", e);
        }
    }
    
    /**
     * 获取所有客户端
     */
    public Set<Object> getAllClientIds() {
        return redisTemplate.opsForHash().keys(getClientsKey());
    }
    
    private String getClientsKey() {
        return "sso:clients";
    }
} 